package com.jrx.anytxn.param.transaction.job.billCompare.config;

import com.google.common.collect.Maps;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.param.transaction.config.AnytxnBatchConfigProperties;
import com.jrx.anytxn.param.transaction.config.BillCompareConfig;
import com.jrx.anytxn.param.transaction.job.billCompare.bean.ThirdBillDetilReadBean;
import com.jrx.anytxn.param.transaction.job.billCompare.step.BillDetailForDailyProcessor;
import com.jrx.anytxn.param.transaction.job.billCompare.step.BillDetailForFKProcessor;
import com.jrx.anytxn.param.transaction.job.billCompare.step.BillDetailForQXProcessor;
import com.jrx.anytxn.param.transaction.job.billCompare.step.BillDetailForTKProcessor;
import com.jrx.anytxn.param.transaction.job.billCompare.step.BillDetailForXFProcessor;
import com.jrx.anytxn.param.transaction.job.billCompare.step.BillDetailForYJKProcessor;
import com.jrx.anytxn.param.transaction.job.billCompare.step.BillDetailWriter;
import com.jrx.anytxn.param.transaction.job.billCompare.step.ThirdDetailReadListener;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.AmLoanMainInfo;
import com.jrx.anytxn.transaction.entity.TlDailyAccountLog;
import com.jrx.anytxn.transaction.entity.TlDisbursementLog;
import com.jrx.anytxn.transaction.entity.TlPaymentLog;
import com.jrx.anytxn.transaction.entity.TlRefundLog;
import com.jrx.anytxn.transaction.entity.TlTransactionInfo;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.batch.MyBatisPagingItemReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SimpleAsyncTaskExecutor;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.Objects;


/**
 * 外部对账-txn内部交易流水汇总job
 *
 * @author : zcc
 * 2020/11/30
 */
@Configuration
public class ThirdBillDetailReadConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(ThirdBillDetailReadConfiguration.class);

    @Resource(name = "bizSqlSessionFactory")
    SqlSessionFactory sqlSessionFactory;
    @Autowired
    public JobBuilderFactory jobBuilderFactory;
    @Autowired
    public StepBuilderFactory stepBuilderFactory;
    @Autowired
    private IOrganizationTableService organizationTableService;
    @Autowired
    private AnytxnBatchConfigProperties anytxnBatchConfigProperties;
    @Autowired
    private BillDetailWriter billDetailWriter;
    @Autowired
    private ThirdDetailReadListener thirdDetailReadListener;
    @Autowired
    private BillDetailForQXProcessor billDetailForQXProcessor;
    @Autowired
    private BillDetailForXFProcessor billDetailForXFProcessor;
    @Autowired
    private BillDetailForTKProcessor billDetailForTKProcessor;
    @Autowired
    private BillDetailForYJKProcessor billDetailForYJKProcessor;
    @Autowired
    private BillDetailForFKProcessor billDetailForFKProcessor;
    @Autowired
    private BillDetailForDailyProcessor billDetailForDailyProcessor;
    @Resource
    private BillCompareConfig billCompareConfig;

    @Bean
    public Job thirdBillDetailJob() {
        return jobBuilderFactory.get("thirdBillDetailJob").incrementer(new RunIdIncrementer()).listener(thirdDetailReadListener)
                // 消费
                .start(billDetailForXFReadStep())
                // 取消
                .next(billDetailForQXReadStep())
                // 退款
                .next(billDetailForTKReadStep())
                // 溢缴款
                .next(billDetailForYJKReadStep())
                // 放款
                .next(billDetailForFKReadStep())
                // T24日终汇总
                .next(billDetailForDailyReadStep())
                .build();
    }

    @Bean
    public Step billDetailForXFReadStep() {
        return stepBuilderFactory.get("billDetailForXFReadStep")
                .<AmLoanMainInfo, ThirdBillDetilReadBean>chunk(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getChunkLimit())
                .reader(billDetailForXFReader())
                .processor(billDetailForXFProcessor)
                .writer(billDetailWriter)
                .taskExecutor(new SimpleAsyncTaskExecutor())
                .throttleLimit(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getThrottleLimit())//多线程*/
                .build();
    }

    @Bean
    @StepScope
    public MyBatisPagingItemReader<AmLoanMainInfo> billDetailForXFReader() {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.XIB_ORG_NUMBER);
        // 设置指定对账日期
        Date today = billCompareConfig.getToday();
        if (Objects.nonNull(today)) {
            org.setToday(today);
        }
        MyBatisPagingItemReader<AmLoanMainInfo> reader = new MyBatisPagingItemReader();
        reader.setSaveState(false);
        reader.setSqlSessionFactory(sqlSessionFactory);
        reader.setPageSize(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getPageSize());
        reader.setQueryId("com.jrx.anytxn.transaction.mapper.ext.ExtAmLoanMainInfoMapper.selectByPostingDateAndLoanTypeForBatch");
        Map<String, Object> param = Maps.newHashMapWithExpectedSize(4);
        param.put("tenantId", org.getTenantId());
        param.put("businessDate", org.getToday());
        String thirdChannel = billCompareConfig.getThirdChannel();
        boolean contains = Arrays.asList("PCP", "T24").contains(thirdChannel);
        param.put("loanType", contains ? TransBizConstant.LOAN_TYPE_7 : TransBizConstant.LOAN_TYPE_4);
        param.put("thirdChannel", thirdChannel);
        reader.setParameterValues(param);
        return reader;
    }

    @Bean
    public Step billDetailForQXReadStep() {
        return stepBuilderFactory.get("billDetilForQXReadStep")
                .<TlTransactionInfo, ThirdBillDetilReadBean>chunk(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getChunkLimit())
                .reader(billDetailForQXReader())
                .processor(billDetailForQXProcessor)
                .writer(billDetailWriter)
                .taskExecutor(new SimpleAsyncTaskExecutor())
                .throttleLimit(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getThrottleLimit())//多线程*/
                .build();
    }

    @Bean
    @StepScope
    public MyBatisPagingItemReader<TlTransactionInfo> billDetailForQXReader() {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.XIB_ORG_NUMBER);
        // 设置指定对账日期
        Date today = billCompareConfig.getToday();
        if (Objects.nonNull(today)) {
            org.setToday(today);
        }
        MyBatisPagingItemReader<TlTransactionInfo> reader = new MyBatisPagingItemReader();
        reader.setSaveState(false);
        reader.setSqlSessionFactory(sqlSessionFactory);
        reader.setPageSize(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getPageSize());
        reader.setQueryId("com.jrx.anytxn.transaction.mapper.ext.ExtTlTransactionInfoMapper.selectByPostingDateForBatch");
        Map<String, Object> param = Maps.newHashMapWithExpectedSize(4);
        param.put("tenantId", org.getTenantId());
        param.put("businessDate", org.getToday());
        param.put("txnCode", TransBizConstant.TXN_CODE_INSTSUM_REVOCATION);
        param.put("thirdChannel", billCompareConfig.getThirdChannel());
        reader.setParameterValues(param);
        return reader;
    }

    @Bean
    public Step billDetailForTKReadStep() {
        return stepBuilderFactory.get("billDetilForTKReadStep")
                .<TlPaymentLog, ThirdBillDetilReadBean>chunk(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getChunkLimit())
                .reader(billDetailForTKReader())
                .processor(billDetailForTKProcessor)
                .writer(billDetailWriter)
                .taskExecutor(new SimpleAsyncTaskExecutor())
                .throttleLimit(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getThrottleLimit())//多线程*/
                .build();
    }

    @Bean
    @StepScope
    public MyBatisPagingItemReader<TlPaymentLog> billDetailForTKReader() {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.XIB_ORG_NUMBER);
        // 设置指定对账日期
        Date today = billCompareConfig.getToday();
        if (Objects.nonNull(today)) {
            org.setToday(today);
        }
        MyBatisPagingItemReader<TlPaymentLog> reader = new MyBatisPagingItemReader();
        reader.setSaveState(false);
        reader.setSqlSessionFactory(sqlSessionFactory);
        reader.setPageSize(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getPageSize());
        // 退款和溢缴款一起查询
        reader.setQueryId("com.jrx.anytxn.transaction.mapper.ext.ExtTlPaymentLogMapper.selectByTenantIdAndBusDateAndPaymentType");
        Map<String, Object> param = Maps.newHashMapWithExpectedSize(4);
        param.put("tenantId", org.getTenantId());
        param.put("paymentType", TransBizConstant.REPAYMENT_TYPE_REFUND);
        param.put("businessDate", org.getToday());
        param.put("thirdChannel", billCompareConfig.getThirdChannel());
        reader.setParameterValues(param);
        return reader;
    }

    @Bean
    public Step billDetailForYJKReadStep() {
        return stepBuilderFactory.get("billDetailForYJKReadStep")
                .<TlRefundLog, ThirdBillDetilReadBean>chunk(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getChunkLimit())
                .reader(billDetailForYJKReader())
                .processor(billDetailForYJKProcessor)
                .writer(billDetailWriter)
                .taskExecutor(new SimpleAsyncTaskExecutor())
                .throttleLimit(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getThrottleLimit())//多线程*/
                .build();
    }

    @Bean
    @StepScope
    public MyBatisPagingItemReader<TlRefundLog> billDetailForYJKReader() {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.XIB_ORG_NUMBER);
        // 设置指定对账日期
        Date today = billCompareConfig.getToday();
        if (Objects.nonNull(today)) {
            org.setToday(today);
        }
        MyBatisPagingItemReader<TlRefundLog> reader = new MyBatisPagingItemReader<>();
        reader.setSaveState(false);
        reader.setSqlSessionFactory(sqlSessionFactory);
        reader.setPageSize(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getPageSize());
        // 退款和溢缴款一起查询
        reader.setQueryId("com.jrx.anytxn.transaction.mapper.ext.ExtTlRefundLogMapper.queryRefundByBusinessDate");
        Map<String, Object> param = Maps.newHashMapWithExpectedSize(2);
        param.put("tenantId", org.getTenantId());
        param.put("businessDate", org.getToday());
        param.put("thirdChannel", billCompareConfig.getThirdChannel());
        reader.setParameterValues(param);
        return reader;
    }

    @Bean
    public Step billDetailForFKReadStep() {
        return stepBuilderFactory.get("billDetailForFKReadStep")
                .<TlDisbursementLog, ThirdBillDetilReadBean>chunk(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getChunkLimit())
                .reader(billDetailForFKReader())
                .processor(billDetailForFKProcessor)
                .writer(billDetailWriter)
                .taskExecutor(new SimpleAsyncTaskExecutor())
                .throttleLimit(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getThrottleLimit())//多线程*/
                .build();
    }

    @Bean
    @StepScope
    public MyBatisPagingItemReader<TlDisbursementLog> billDetailForFKReader() {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.XIB_ORG_NUMBER);
        // 设置指定对账日期
        Date today = billCompareConfig.getToday();
        if (Objects.nonNull(today)) {
            org.setToday(today);
        }
        MyBatisPagingItemReader<TlDisbursementLog> reader = new MyBatisPagingItemReader<>();
        reader.setSaveState(false);
        reader.setSqlSessionFactory(sqlSessionFactory);
        reader.setPageSize(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getPageSize());
        reader.setQueryId("com.jrx.anytxn.transaction.mapper.ext.ExtTlDisbursementLogMapper.selectDailyT24NotAccountData");
        Map<String, Object> param = Maps.newHashMapWithExpectedSize(5);

        // 上一业务日期
        param.put("businessDate",org.getToday());
        // 租户id
        param.put("tenantId", org.getTenantId());
        // 日终T24核心汇总记账产品列表
        param.put("productIds", null);
        // 收款账户类型(0-本行，1-他行)
        param.put("payeeAccountType", TransBizConstant.CARD_TYPE_0);
        // 日终T24核心汇总记账状态 S-记账成功，F-记账失败，O-记账状态未知，默认D-未记账
        param.put("keepAccountStatusList", null);

        reader.setParameterValues(param);
        return reader;
    }

    @Bean
    public Step billDetailForDailyReadStep() {
        return stepBuilderFactory.get("billDetailForDailyReadStep")
                .<TlDailyAccountLog, ThirdBillDetilReadBean>chunk(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getChunkLimit())
                .reader(billDetailForDailyReader())
                .processor(billDetailForDailyProcessor)
                .writer(billDetailWriter)
                .taskExecutor(new SimpleAsyncTaskExecutor())
                .throttleLimit(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getThrottleLimit())//多线程*/
                .build();
    }

    @Bean
    @StepScope
    public MyBatisPagingItemReader<TlDailyAccountLog> billDetailForDailyReader() {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.XIB_ORG_NUMBER);
        // 设置指定对账日期
        Date today = billCompareConfig.getToday();
        if (Objects.nonNull(today)) {
            org.setToday(today);
        }
        MyBatisPagingItemReader<TlDailyAccountLog> reader = new MyBatisPagingItemReader<>();
        reader.setSaveState(false);
        reader.setSqlSessionFactory(sqlSessionFactory);
        reader.setPageSize(anytxnBatchConfigProperties.getBatchBillCompareConfiguration().getPageSize());
        reader.setQueryId("com.jrx.anytxn.transaction.mapper.ext.ExtTlDailyAccountLogMapper.selectDailyByBusinessDate");
        Map<String, Object> param = Maps.newHashMapWithExpectedSize(3);

        // 上一业务日期
        param.put("businessDate",org.getToday());
        // 租户id
        param.put("tenantId", org.getTenantId());
        // 日终T24核心汇总记账状态 S-记账成功，F-记账失败，O-记账状态未知，默认D-未记账
        param.put("returnStatus", Arrays.asList(TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_S,TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_O));

        reader.setParameterValues(param);
        return reader;
    }


}
